//package com.easyforeign.config;
//
//import com.easyforeign.annotation.ForeignColumn;
//import com.fasterxml.jackson.core.JsonGenerator;
//import com.fasterxml.jackson.databind.SerializerProvider;
//import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
//import lombok.SneakyThrows;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import javax.sql.DataSource;
//import java.io.IOException;
//import java.sql.*;
//import java.util.*;
//import java.util.concurrent.ConcurrentHashMap;
//
//public class EasyForeignListPropertyWriter extends BeanPropertyWriter {
//    private final BeanPropertyWriter baseWriter;
//    private final String selfColumn;
//    private final ForeignColumn[] targetColumn;
//    private final String tableName;
//    private final DataSource dataSource;
//    // 缓存： key=表名:外键字段:外键值， value=目标字段名->值
//    private static final ConcurrentHashMap<String, ConcurrentHashMap<String, Optional<List<>>>> TARGET_VALUE_CACHE = new ConcurrentHashMap<>();
//    private static final Logger log = LoggerFactory.getLogger(EasyForeignListPropertyWriter.class);
//
//    public EasyForeignListPropertyWriter(BeanPropertyWriter baseWriter, String selfColumn, ForeignColumn[] targetColumn, String tableName, DataSource dataSource) {
//        super(baseWriter);
//        this.baseWriter = baseWriter;
//        this.selfColumn = selfColumn;
//        this.targetColumn = targetColumn;
//        this.tableName = tableName;
//        this.dataSource = dataSource;
//    }
//
//    @Override
//    public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
//        // 先序列化原字段
//        baseWriter.serializeAsField(bean, gen, prov);
//        // 取得加上注解的字段值（外建值）
//        Object selfColumnValue = baseWriter.get(bean);
//        if (selfColumnValue == null) return;
//        // 取得缓存
//        ConcurrentHashMap<String, Optional<String>> innerMap = getInnerMap(selfColumnValue);
//        // 添加目标字段
//        for (ForeignColumn col : targetColumn) {
//            String value = Optional.ofNullable(innerMap.get(col.column()))
//                    .flatMap(v -> v)
//                    .orElse(null);
//            String columnName = col.alias().isEmpty() ? underlineToCamel(col.column()) : col.alias();
//            writeField(gen, columnName, value);
//        }
//    }
//
//    private void writeField(JsonGenerator gen, String name, String value) throws IOException {
//        if (value == null) gen.writeNullField(name);
//        else gen.writeStringField(name, value);
//    }
//
//    private ConcurrentHashMap<String, Optional<String>> getInnerMap(Object selfColumnValue) {
//        // 获取缓存 key
//        String cacheKey = tableName + ":" + selfColumn + ":" + selfColumnValue;
//        // 从缓存中取出已有的数据，没有则创建 inner map（线程安全）
//        ConcurrentHashMap<String, Optional<String>> innerMap =
//                TARGET_VALUE_CACHE.computeIfAbsent(cacheKey, k -> new ConcurrentHashMap<>());
//
//        // 找出缺失的字段（未在 innerMap 中出现）
//        List<String> missing = new ArrayList<>();
//        for (ForeignColumn col : targetColumn) {
//            if (!innerMap.containsKey(col.column())) {
//                missing.add(col.column());
//            }
//        }
//
//        // 若存在缺失字段，则仅查询缺失字段并合并到 innerMap
//        if (!missing.isEmpty()) {
//            Map<String, String> fetched = getTargetColumnValue(selfColumnValue, selfColumn,
//                    missing.toArray(new String[0]), tableName, dataSource);
//
//            // 把 fetch 到的结果（包括 null）放入 innerMap，使用 putIfAbsent 保证已有缓存不被覆盖
//            for (String col : missing) {
//                // 使用 Optional 表达可能为 null 的值（ConcurrentHashMap 不允许 null）
//                innerMap.putIfAbsent(col, Optional.ofNullable(fetched.get(col)));
//            }
//        }
//        return innerMap;
//    }
//
//    @SneakyThrows
//    public static Map<String, String> getTargetColumnValue(
//            Object selfColumnValue,
//            String selfColumn,
//            String[] targetColumn,
//            String tableName,
//            DataSource dataSource) {
//
//        Map<String, String> resultMap = new HashMap<>();
//        String targetColumns = String.join(",", targetColumn);
//        String querySql = "SELECT " + targetColumns + " FROM " + tableName + " WHERE " + selfColumn + " = ?";
//
//        int rowCount = 0;
//
//        try (Connection connection = dataSource.getConnection();
//             PreparedStatement stmt = connection.prepareStatement(querySql)) {
//
//            stmt.setObject(1, selfColumnValue);
//            try (ResultSet rs = stmt.executeQuery()) {
//                ResultSetMetaData metaData = rs.getMetaData();
//                int columnCount = metaData.getColumnCount();
//
//                while (rs.next()) {
//                    rowCount++;
//
//                    // 只取第一条结果
//                    if (rowCount == 1) {
//                        for (int i = 1; i <= columnCount; i++) {
//                            String columnName = metaData.getColumnName(i);
//                            Object columnValue = rs.getObject(i);
//                            if (Arrays.asList(targetColumn).contains(columnName)) {
//                                resultMap.put(columnName, columnValue == null ? null : columnValue.toString());
//                            }
//                        }
//                    }
//                }
//            }
//
//            // 若返回多条，打印警告日志
//            if (rowCount > 1) {
//                log.warn("[EasyForeign] 表：{} 中字段 {}值为 {},查询到 {} 条记录。理论应唯一，已默认取第一条，请检查数据唯一性。",
//                        tableName, selfColumn, selfColumnValue, rowCount);
//            }
//
//        } catch (SQLException e) {
//            log.error("[EasyForeign] 查询外键映射异常，表: {}, 字段: {}, 值: {}, 错误: {}",
//                    tableName, selfColumn, selfColumnValue, e.getMessage(), e);
//        }
//
//        return resultMap;
//    }
//
//
//    /**
//     * 下划线转驼峰
//     */
//    private static String underlineToCamel(String underline) {
//        if (underline == null || underline.isEmpty()) {
//            return underline;
//        }
//        StringBuilder result = new StringBuilder();
//        boolean upperCase = false;
//        for (int i = 0; i < underline.length(); i++) {
//            char c = underline.charAt(i);
//            if (c == '_') {
//                upperCase = true;
//            } else if (upperCase) {
//                result.append(Character.toUpperCase(c));
//                upperCase = false;
//            } else {
//                result.append(Character.toLowerCase(c));
//            }
//        }
//        return result.toString();
//    }
//}
